import angular from 'angular';

ngPopoverDirective.$inject = ['$timeout', '$document', '$compile', '$templateCache'];

function ngPopoverDirective($timeout, $document, $compile, $templateCache) {
  return {
    restrict: 'A',
    scope: {
      ngPopover: '=?',           // 配置对象
      popoverTitle: '@',         // 标题
      popoverContent: '@',       // 简单文本内容
      popoverTemplate: '@',      // 自定义模板 URL
      popoverHtml: '@',          // HTML 内容
      popoverPlacement: '@',     // 位置: top, bottom, left, right
      popoverTrigger: '@',       // 触发方式: click, hover, manual
      popoverShow: '=?',         // 手动控制显示/隐藏
      popoverAnimation: '@',     // 动画类名
      popoverContainer: '@'      // 容器选择器
    },
    link: function(scope, element, attrs) {
      // 默认配置
      var config = angular.extend({
        title: '',
        content: '',
        template: '',
        html: false,
        placement: 'top',
        trigger: 'click',
        animation: 'fade',
        container: 'body',
        show: false
      }, scope.ngPopover || {});

      // 合并 data-* 属性
      config.title = scope.popoverTitle || config.title;
      config.content = scope.popoverContent || config.content;
      config.template = scope.popoverTemplate || config.template;
      config.html = scope.popoverHtml !== undefined ? scope.popoverHtml === 'true' : config.html;
      config.placement = scope.popoverPlacement || config.placement;
      config.trigger = scope.popoverTrigger || config.trigger;
      config.animation = scope.popoverAnimation || config.animation;
      config.container = scope.popoverContainer || config.container;

      var popoverElement = null;
      var popoverScope = null;
      var isShowing = false;
      var isAnimating = false;

      // 创建 popover 元素
      function createPopover() {
        if (popoverElement) {
          return;
        }

        // 创建子 scope
        popoverScope = scope.$new();
        popoverScope.title = config.title;
        popoverScope.content = config.content;
        popoverScope.placement = config.placement;
        popoverScope.html = config.html;

        var templateContent;
        if (config.template) {
          // 使用自定义模板
          templateContent = $templateCache.get(config.template);
          if (!templateContent) {
            console.error('Template not found: ' + config.template);
            return;
          }
        } else {
          // 使用默认模板
          templateContent = getDefaultTemplate();
        }

        popoverElement = $compile(templateContent)(popoverScope);

        // 添加到容器
        var container = angular.element(document.querySelector(config.container) || document.body);
        container.append(popoverElement);

        // 初始隐藏
        popoverElement.css({
          display: 'none',
          position: 'absolute',
          zIndex: 1060
        });
      }

      // 默认模板
      function getDefaultTemplate() {
        return '<div class="ng-popover ng-popover-{{placement}}" ng-class="{\'ng-popover-show\': visible}">' +
               '  <div class="ng-popover-arrow"></div>' +
               '  <div class="ng-popover-inner">' +
               '    <div class="ng-popover-title" ng-if="title">{{title}}</div>' +
               '    <div class="ng-popover-content">' +
               '      <div ng-if="!html">{{content}}</div>' +
               '      <div ng-if="html" ng-bind-html="content"></div>' +
               '    </div>' +
               '  </div>' +
               '</div>';
      }

      // 计算位置
      function calculatePosition() {
        if (!popoverElement) return;

        var triggerRect = element[0].getBoundingClientRect();
        var popoverRect = popoverElement[0].getBoundingClientRect();
        var scrollTop = window.pageYOffset || document.documentElement.scrollTop;
        var scrollLeft = window.pageXOffset || document.documentElement.scrollLeft;

        var position = {
          top: 0,
          left: 0
        };

        var arrowSize = 8; // 箭头大小
        var offset = 10; // 偏移量

        switch (config.placement) {
          case 'top':
            position.top = triggerRect.top + scrollTop - popoverRect.height - offset;
            position.left = triggerRect.left + scrollLeft + (triggerRect.width - popoverRect.width) / 2;
            break;
          case 'bottom':
            position.top = triggerRect.bottom + scrollTop + offset;
            position.left = triggerRect.left + scrollLeft + (triggerRect.width - popoverRect.width) / 2;
            break;
          case 'left':
            position.top = triggerRect.top + scrollTop + (triggerRect.height - popoverRect.height) / 2;
            position.left = triggerRect.left + scrollLeft - popoverRect.width - offset;
            break;
          case 'right':
            position.top = triggerRect.top + scrollTop + (triggerRect.height - popoverRect.height) / 2;
            position.left = triggerRect.right + scrollLeft + offset;
            break;
          default:
            position.top = triggerRect.top + scrollTop - popoverRect.height - offset;
            position.left = triggerRect.left + scrollLeft + (triggerRect.width - popoverRect.width) / 2;
        }

        popoverElement.css({
          top: position.top + 'px',
          left: position.left + 'px'
        });
      }

      // 显示 popover
      function show() {
        if (isShowing || isAnimating) return;

        createPopover();
        isAnimating = true;

        popoverElement.css('display', 'block');

        // 延迟计算位置，确保元素已渲染
        $timeout(function() {
          calculatePosition();
          popoverScope.visible = true;
          isShowing = true;
          isAnimating = false;
        }, 10);
      }

      // 隐藏 popover
      function hide() {
        if (!isShowing || isAnimating) return;

        isAnimating = true;
        popoverScope.visible = false;

        $timeout(function() {
          if (popoverElement) {
            popoverElement.css('display', 'none');
          }
          isShowing = false;
          isAnimating = false;
        }, 200); // 等待动画完成
      }

      // 切换显示状态
      function toggle() {
        if (isShowing) {
          hide();
        } else {
          show();
        }
      }

      // 绑定触发事件
      function bindTriggers() {
        if (config.trigger === 'click') {
          element.on('click', function(event) {
            event.preventDefault();
            event.stopPropagation();
            $timeout(function() {
              toggle();
            });
          });
        } else if (config.trigger === 'hover') {
          element.on('mouseenter', function() {
            $timeout(function() {
              show();
              // 在显示后绑定 popover 的 hover 事件
              if (popoverElement) {
                popoverElement.on('mouseenter', function() {
                  $timeout.cancel(hideTimer);
                });

                popoverElement.on('mouseleave', function() {
                  hideTimer = $timeout(function() {
                    hide();
                  }, 100);
                });
              }
            });
          });

          var hideTimer;
          element.on('mouseleave', function() {
            hideTimer = $timeout(function() {
              hide();
            }, 100);
          });
        }
      }

      // 点击外部关闭
      function onDocumentClick(event) {
        if (!isShowing) return;

        var clickedElement = event.target;
        var clickedInTrigger = element[0].contains(clickedElement);
        var clickedInPopover = popoverElement && popoverElement[0].contains(clickedElement);

        if (!clickedInTrigger && !clickedInPopover) {
          $timeout(function() {
            hide();
          });
        }
      }

      // 监听手动控制
      if (attrs.popoverShow !== undefined) {
        scope.$watch('popoverShow', function(newVal) {
          if (newVal) {
            show();
          } else {
            hide();
          }
        });
      }

      // 初始化
      bindTriggers();

      if (config.trigger === 'click') {
        $document.on('click', onDocumentClick);
      }

      // 监听窗口滚动和调整大小
      var resizeHandler = function() {
        if (isShowing) {
          calculatePosition();
        }
      };

      angular.element(window).on('scroll resize', resizeHandler);

      // 清理
      scope.$on('$destroy', function() {
        if (popoverElement) {
          popoverElement.remove();
        }
        if (popoverScope) {
          popoverScope.$destroy();
        }
        $document.off('click', onDocumentClick);
        angular.element(window).off('scroll resize', resizeHandler);
      });

      // 暴露方法到 scope（可选）
      scope.showPopover = show;
      scope.hidePopover = hide;
      scope.togglePopover = toggle;
    }
  };
}

export default ngPopoverDirective;
